package br.sed.theenemy.model.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import br.sed.theenemy.business.exception.DBException;
import br.sed.theenemy.business.exception.InvalidUniqueBeanException;
import br.sed.theenemy.business.exception.InvalidUserException;
import br.sed.theenemy.model.bean.User;
import br.sed.theenemy.presentation.EnemyConstants;

/**
 * 
 * @author JulioCB
 * @email jcbjulio@gmail.com
 *
 */
public class UserDao extends AbstractDao{

	private static DateFormat DATE_FORMAT_DB = new SimpleDateFormat(EnemyConstants.SIMPLE_DATE_FORMAT_DB);
	
	// Unica instancia da classe
	protected static UserDao instanceDao;
	
	public User create(User user) throws DBException{
		Long userId = getId();
		user.setId(userId);
		user.setImgUrl("http://shhmooze.com/images/android.jpg");
		String sql = "insert into user (id, first_name, last_name, email, pass, gender, born_date, photo) values " +
					 "("+user.getId()+"," +
					 "'"+user.getFirstName()+"', " +
					 "'"+user.getLastName()+"', " +
					 "'"+user.getEmail()+"', " +
					 "'"+user.getPass()+"', " +
					 "'"+user.getGender()+"', " +
					 "'"+DATE_FORMAT_DB.format(user.getBornDate())+"', " +
					 "'"+user.getImgUrl()+"')";			
		//System.out.println("Log:"+sql);
		executeQuery(sql, "Error: Insert User");
		return user;
	}	
	
	public List<User> findByPieceOfName(String pName, Integer start, Integer max) throws SQLException, ParseException, DBException{
		String sql = "select * from user where first_name like '%"+ pName +"%' limit "+ max +" offset "+ start;
		ResultSet result = null;

		result = getRS(sql);
		
		List<User> userList = fillUserList(result);
		result.close();
		closeConnection();
		return userList;
	}
	
	public List<User> findRandom(Integer max) throws SQLException, ParseException, DBException{
		String sql = "select * from user order by rand() limit "+ max;
		ResultSet result = null;

		result = getRS(sql);
		
		List<User> userList = fillUserList(result);
		result.close();
		closeConnection();
		return userList;
	}
	
	public Integer countByPieceOfName(String pName) throws SQLException, DBException{
		String sql = "select count(1) total from user where first_name like '%"+ pName +"%'";
		ResultSet result = null;
		
		result = getRS(sql);
		
		result.next();
		int total = result.getInt("total");
		result.close();
		closeConnection();
		return total;
	}
	
	public User findUserByEmail(String email) throws SQLException, NumberFormatException, ParseException, InvalidUniqueBeanException, InvalidUserException, DBException{
		String sql = "select * from user where email = '"+ email +"'";
		ResultSet result = null;
		
		result = getRS(sql);
		User user = getUser(result);
		result.close();
		closeConnection();
		return user;
	}
	
	public User findUserById(Long userId) throws SQLException, NumberFormatException, ParseException, InvalidUniqueBeanException, InvalidUserException, DBException{
		String sql = "select * from user where id = '"+ userId +"'";
		ResultSet result = null;
		
		result = getRS(sql);
		User user = getUser(result);
		result.close();
		closeConnection();
		return user;
	}
	
	public void update(User user) throws DBException{
		String sql = "update user set first_name='"+user.getFirstName()+
									"', last_name='"+user.getLastName()+
									"', gender='"+user.getGender()+
									"', born_date='"+DATE_FORMAT_DB.format(user.getBornDate())+
									"' where id='"+user.getId()+"'";

		executeQuery(sql, "Error: Updating User");
	}
	
	public void changePassword(User user) throws DBException{
		String sql = "update user set pass='"+user.getPass()+
									"' where id='"+user.getId()+"'";

		executeQuery(sql, "Error: Updating User Password");
	}
	
	public void changeImage(User user) throws DBException{
        String sql = "update user set photo='"+user.getImgUrl()+
                                    "' where id='"+user.getId()+"'";

        executeQuery(sql, "Error: Updating User Password");
    }
	
	public void delete(User user){
		//TODO Delete usuário
	}
	
	public static UserDao getInstance(){
		
		// Verifica se ja tem instancia
		if ( instanceDao == null ){			
			instanceDao = new UserDao();			
		}
		
		return instanceDao;
		
	}
	
	public static List<User> fillUserList(ResultSet result) throws NumberFormatException, SQLException, ParseException{
		List<User> userList = new ArrayList<User>();
		while(result.next()){
			User user = new User();
			user.setId(Long.parseLong(result.getString("id")));
			user.setBornDate(DATE_FORMAT_DB.parse(result.getString("born_date")));
			user.setEmail(result.getString("email"));
			user.setFirstName(result.getString("first_name"));
			user.setGender(result.getString("gender"));
			user.setLastName(result.getString("last_name"));
			user.setPass(result.getString("pass"));
			user.setImgUrl(result.getString("photo"));
			userList.add(user);
		}
		return userList;
	}
	
	public static User getUser(ResultSet result) throws InvalidUniqueBeanException, NumberFormatException, SQLException, ParseException, InvalidUserException{
		List<User> userList = fillUserList(result);
		if(userList.size()==1){
			return userList.get(0);	
		}else if(userList.size()<1){
		    throw new InvalidUserException("User not found");
		}else{
			throw new InvalidUniqueBeanException("Error getting user, not unique");
		}
	}
}
